<?php

namespace Biz\service\springHomeDecActivity;



use Biz\cache\lottery\CSpringHomeVote;
use Biz\model\springHomeDecActivity\MSpringHomeDecUserLottery;
use Biz\model\springHomeDecActivity\VoteRecord;
use Biz\model\springHomeDecActivity\Wish;
use Doraemon\model\AdmUserType;
use Doraemon\model\DeviceBlackWhite;
use Doraemon\service\User as sUser;
use Doraemon\tools\HhzClient;
use Doraemon\tools\Ip;
use Doraemon\tools\Log;
use Exception;

class SSpringHomeDecVote
{

    protected $_uid;
    protected $_wish_uid;
    protected $_complete;
    protected $_user_identity_mark;
    protected $_user_quality;
    protected $_now;
    protected $_did;
    protected $_lock;
    protected $_votes = 0;
    protected $_activity_life = ['2022-03-21 00:00:00', '2022-04-12 00:00:00'];
    protected static $_add_votes = 10;
    protected static $_add_first_votes = 50;
    protected static $code = 2;
    /**
     * @var Wish
    */
    protected $_wish; //许愿家

    public function __construct($uid, $wish_uid, $date = null)
    {
        $this->_uid = $uid;
        $this->_did = HhzClient::getDid();
        $this->_wish_uid = $wish_uid;
        $this->_now = $date ?: date('Y-m-d H:i:s');
    }

    public function __destruct()
    {
        if ($this->_lock) CSpringHomeVote::unlock($this->_uid, $this->_lock);
    }


    public function run()
    {
        $code = 1;
        $msg = '';
        $data = null;
        $real_msg = '';
        $response = [
            'code' => &$code,
            'msg' => &$msg,
            'data' => &$data,
        ];
        try {
            // 获取用户信息
            $this->getUserInfo();
            // 过滤规则
            $this->rules();
            // 投票
            $this->vote();

            $data = $this->_votes;
        } catch (Exception $e) {
            $code = $e->getCode();
            if ($code == self::$code) {
                $msg = '网络异常，请稍后重试~';
            } else {
                $msg = $e->getMessage();
            }
            $real_msg = $e->getMessage();
        }
        Log::info('家装节日志:投票', [
            'uid' => $this->_uid,
            'did' => $this->_did,
            'wish_uid' => $this->_wish_uid,
            'now' => $this->_now,
            'msg' => $msg,
            'real_msg' => $real_msg,
        ]);
        return $response;
    }

    protected function getUserInfo()
    {
        $aMemberQualityInfo = AdmUserType::getByUid($this->_uid) ?: [];
        $this->_user_quality = $aMemberQualityInfo['quality'] ?? '';
        $this->_user_identity_mark = trim($aMemberQualityInfo['identity_mark'] ?? '');
        $info = Wish::getInfo($this->_wish_uid);
        if (empty($info)) throw new Exception('心愿不存在');
        $this->_wish = new Wish($info);
    }

    /**
     * 规则限制
     * @throws Exception
     */
    protected function rules()
    {
        //2.1 活动时间的的控制
        if ($this->_now <= $this->_activity_life[0]) throw new Exception('投票活动未开始', self::$code);
        if ($this->_now >= $this->_activity_life[1]) throw new Exception('投票活动未开始', self::$code);
        if ($this->_uid == $this->_wish_uid) throw new Exception('自己不能给自己投票', self::$code);
        //2.2 每个用户活动期内仅可为同一用户加砖1次
        if (VoteRecord::dataCount(['uid' => $this->_uid, 'to_uid' => $this->_wish_uid])) throw new Exception('每个用户活动期内仅可为同一用户加砖1次');

        //2.4 B级用户、批量刷交互、设备批量注册、IP批量注册、批量注册、积分反垃圾、被拉黑的设备ID、测试账号、疑似商业用户、机器人账号、注册后没有修改过昵称的账号
        if ($this->_user_quality == AdmUserType::B1)  throw new Exception('B级用户', self::$code);
        if (DeviceBlackWhite::selectByWhere([
            'device_id' => $this->_did,
            'data_type' => DeviceBlackWhite::DEVICE_BLACK_TYPE,
            'data_status' =>DeviceBlackWhite::STATUS_NORMAL,
        ])) throw new Exception('被拉黑的设备ID:' . $this->_did, self::$code);
        if (strpos($this->_user_identity_mark, "批量") !== false) throw new Exception('批量标识的账号', self::$code);
        if (strpos($this->_user_identity_mark, "测试账号") !== false) throw new Exception('测试账号', self::$code);
        if (strpos($this->_user_identity_mark, "疑似商业用户") !== false) throw new Exception('疑似商业用户', self::$code);
        if (strpos($this->_user_identity_mark, "机器人账号") !== false) throw new Exception('机器人账号', self::$code);
//        if (strpos($this->_user_identity_mark, "积分反垃圾") !== false) throw new Exception('积分反垃圾', self::$code);
        // 反垃圾
        if (!CSpringHomeVote::incrDidTimes($this->_did . ":" . $this->_wish_uid, 3)) throw new \Exception('单日同一设备为同一用户投票超过3次', self::$code);
        $ip = Ip::getClientIp();
        if (!CSpringHomeVote::incrIpTimes($ip . ":" . $this->_wish_uid, 300)) throw new \Exception('单日同一ip为同一用户投票超过300次', self::$code);
    }


    /**
     * @throws Exception
     */
    public function vote()
    {
        $this->_lock = CSpringHomeVote::lock($this->_uid);
        if (!$this->_lock) throw new Exception('获取锁失败');

        Wish::action(function () {
            $wish_id = $this->_wish->id;
            $v = $this->_wish->v;
            $user_lottery = MSpringHomeDecUserLottery::dataSelectInfo(['uid' => $this->_uid]);
            $user_info = sUser::getUser($this->_uid);
            $is_new = ((time() - $user_info['addtime']) < 86400) && ($user_lottery['vote'] == 0);
//            $is_new = true;
            $brick_count = $is_new ? self::$_add_first_votes : self::$_add_votes;
            //1.记录抽奖记录
            if (!VoteRecord::addRecord($this->_uid, $wish_id, $this->_wish_uid, (int)$is_new, $brick_count)) throw new Exception('生成投票记录失败');
            //2.记录中奖统计
            if (!MSpringHomeDecUserLottery::addVoteRecord($this->_uid, $user_lottery['v'] ?? 0, $is_new)) throw new Exception('生成投票统计失败');
            //3.增加砖头
            if (!Wish::increaseBrick($this->_wish_uid, $v, $brick_count)) throw new Exception('增加砖头失败');

            $this->_votes = $brick_count;
        });
    }


}